﻿var map,
    loadedVenues = [],
    loadedVenueIds = {},
    _mapBounds,
    _zoom,
    venueFactory;

function GetMap() {
    var mapOptions =
    {
        credentials: "YOUR_BING_MAPS_KEY",
        zoom: 2,
        showBreadcrumb : true
    };

    map = new Microsoft.Maps.Map(document.getElementById("myMap"), mapOptions);

    //Load the venue map module
    Microsoft.Maps.loadModule('Microsoft.Maps.VenueMaps', {
        callback: function () {
            venueFactory = new Microsoft.Maps.VenueMaps.VenueMapFactory(map);

            //Use a throttled event to reduce the number of unwanted events being fired.
            Microsoft.Maps.Events.addThrottledHandler(map, 'viewchangeend', GetNearbyVenues, 250);
        }
    });
}

function GetNearbyVenues() {
    _mapBounds = map.getBounds();
    _zoom = map.getZoom();

    //Dispose a venue if it is outside of the map view or if the zoom  level is too high
    var venuesInView = [], venue;

    for (var i = 0; i < loadedVenues.length; i++) {
        venue = loadedVenues[i];

        if (_zoom < 14 || !_mapBounds.contains(venue.center)) {
            delete loadedVenueIds[venue.id];
            venue.dispose();
        } else {
            venuesInView.push(venue);
        }
    }

    loadedVenues = venuesInView;

    if (_zoom >= 14) {
        // Search for venues that are within 4km of the center of the map
        venueFactory.getNearbyVenues({ map: map, location: map.getCenter(), radius: 4000, callback: DisplayNearbyVenues });
    }
}

function DisplayNearbyVenues(venues) {
    if (venues) {
        //Load new venues that are in view
        for (var i = 0; i < venues.length; i++) {
            if (loadedVenueIds[venues[i].metadata.MapId] == undefined) {
                venueFactory.create({
                    venueMapId: venues[i].metadata.MapId,
                    success: function (v) {
                        if (_mapBounds.contains(v.center)) {

                            //Handle close event of venue
                            Microsoft.Maps.Events.addHandler(v, 'close', function (e) {
                                delete loadedVenueIds[v.id];
                                
                                //Remove venue from loadedVenues array
                                for (var j = 0; j < loadedVenues.length; j++) {
                                    if (loadedVenues[j].id == v.id) {
                                        loadedVenues.splice(j , j+1);
                                        break;
                                    }
                                }

                                v.dispose();
                            });

                            loadedVenues.push(v);
                            loadedVenueIds[v.id] = true;
                            v.show();
                        } else {
                            v.dispose();
                        }
                    }
                });
            }
        }
    }
}

//Initialization logic for loading the map control
(function () {
    function initialize() {
        Microsoft.Maps.loadModule('Microsoft.Maps.Map', { callback: GetMap });
    }

    document.addEventListener("DOMContentLoaded", initialize, false);
})();
